namespace CSharedMemory;

using System;
using System.Runtime.InteropServices;

public class CHelper
{
    public const int MemorySize = 128;
    public const string MemoryName = "RobotSensorMem";

    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto, Pack = 1)]
    public class RobotMemory
    {
        public ushort id;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)]
        public float[] sensors;
        public RobotMemory()
        {
            sensors = new float[6];
        }
    };

    public const string libpath = "/home/ubuntu/robot-distance-sensor/CFiles/build/libsharememory.so";
    [DllImport(libpath)]
    public extern static void mmUnlink(string name);

    [DllImport(libpath)]
    public extern static IntPtr mmOpen(string name, int size, ref int out_flag);

    [DllImport(libpath)]
    public extern static IntPtr mmCreateOnOpen(string name, int size, ref int out_flag);

    private static readonly CHelper _instance = new CHelper();
    public static CHelper Instance => _instance;

    public RobotMemory? SensorMemory;
    public bool Ready { get; private set;} 
    private IntPtr memPtr;

    private CHelper() {
        int flag = -999;
        memPtr = mmCreateOnOpen(MemoryName, MemorySize, ref flag);
        if(flag == 0)
        {
            Console.WriteLine("Shared Memory Initisalized.");
            Ready = true;
        }
        else
        {
            Console.Error.WriteLine($"Shared Memory Initialise Failed, Flag: {flag}");
        }
    }

    public void SetMemoryValue(RobotMemory mem)
    {
        if(!Ready)
        {
            Console.Error.WriteLine("[Error] Memory Not Initialized!");
        }

        try
        {
            Marshal.StructureToPtr(mem, memPtr, false);
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }

}